// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// w [author] rhyme_lph
// T [email]  rhymelph@gmail.com
// s [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/app_colors.dart';
import 'package:finance_app/src/common/app_spaces.dart';
import 'package:finance_app/src/entities/expense_detail_entity.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/utils/form_utils.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_button.dart';
import 'package:finance_app/src/widgets/button/normal_float_text_white_button.dart';
import 'package:finance_app/src/widgets/common_app_bar.dart';
import 'package:finance_app/src/widgets/dash_board/transaction_record_title_item.dart';
import 'package:finance_app/src/widgets/input/search_input_field.dart';
import 'package:finance_app/src/widgets/select/reimburse_item_check_box.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/provider/hr_payroll/reimburse/reimburse_approve_provider.dart';
import 'package:finance_app/src/router_gen/router_meta.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:tuple/tuple.dart';

@RouterMeta(paramName: "reimburseApprovePage")
class ReimburseApprovePage extends StatefulWidget {
  final String operation;

  const ReimburseApprovePage({Key key, this.operation}) : super(key: key);

  @override
  _ReimburseApprovePageState createState() => _ReimburseApprovePageState();
}

class _ReimburseApprovePageState extends State<ReimburseApprovePage>
    with PagePresenter<ReimburseApprovePage, ReimburseApproveProvider> {
  @override
  PreferredSizeWidget get appBar => getDefaultAppBar(
        title: widget.operation,
      );

  @override
  Widget get buildEmptyWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              children: [
                AppSpaces.h20,
                SearchInputField(
                  controller: provider.searchController,
                  focusNode: provider.searchFocusNode,
                ),
                Expanded(
                  child: super.buildEmptyWidget,
                ),
              ],
            ),
            _buildBottomBar(),
          ],
        ),
      );

  @override
  Widget get buildWidget => ColoredBox(
        color: Colors.white,
        child: Stack(
          children: [
            Column(
              children: [
                AppSpaces.h20,
                SearchInputField(
                  controller: provider.searchController,
                  focusNode: provider.searchFocusNode,
                ),
                Expanded(
                  child: listBuilder<
                      Tuple2<bool, Map<String, List<ExpenseDetailEntity>>>>(
                    selector: (_, __) => Tuple2(
                        __.hasUp,
                        Map<String, List<ExpenseDetailEntity>>.from(
                            __.groupMap)),
                    builder: (BuildContext context,
                            Tuple2<bool, Map<String, List<ExpenseDetailEntity>>>
                                value,
                            Widget child) =>
                        SmartRefresher(
                      controller: provider.refreshController,
                      onLoading: provider.onLoadMore,
                      onRefresh: provider.onRefresh,
                      enablePullDown: false,
                      enablePullUp: value.item1,
                      child: CustomScrollView(
                        slivers: buildSearchWidget(),
                      ),
                    ),
                  ),
                ),
              ],
            ),
            _buildBottomBar(),
          ],
        ),
      );

  Widget _buildBottomBar() => Positioned(
      bottom: getDp(32) + MediaQuery.of(context).padding.bottom,
      left: 0.0,
      right: 0.0,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          NormalFloatTextWhiteButton(
            title: S.current.cancel,
            onTap: provider.onCancel,
          ),
          SizedBox(
            width: getDp(15),
          ),
          NormalFloatTextButton(
            title: actionName(widget.operation),
            onTap: () => provider.onOperation(widget.operation),
          ),
        ],
      ));

  List<Widget> buildSearchWidget() {
    List<Widget> slivers = [];
    List dataList = [];
    dataList = provider.groupMap.entries.toList();
    for (int i = 0; i < dataList.length; i++) {
      final e = dataList[i];
      slivers.add(buildSliver(e.key, e.value, i == 0));
    }
    return slivers;
  }

  Widget buildSliver(
          String title, List<ExpenseDetailEntity> data, bool isFirst) =>
      SliverStickyHeader(
        header: buildSliverHeader(title: title, isFirst: isFirst),
        sticky: false,
        sliver: SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, i) => buildSliverItem(data, i),
            childCount: data.length,
          ),
        ),
      );

  Widget buildSliverItem(List<ExpenseDetailEntity> data, int i) {
    ExpenseDetailEntity lastItemInList =
        provider.groupMap.entries.toList().map((e) => e.value).last.last;

    return listBuilder<Tuple2<ExpenseDetailEntity, bool>>(
      selector: (_, __) => Tuple2(
          data[i],
          __.currentSelectList.firstWhere((element) => element.id == data[i].id,
                  orElse: () => null) !=
              null),
      builder: (BuildContext context, Tuple2<ExpenseDetailEntity, bool> value,
              Widget child) =>
          Column(
        children: [
          PressedOpacityButton(
            onPressed: () => provider.onSelect(value.item1),
            child: ReimburseItemCheckBox(
              title: value.item1.items.map((e) => e.category?.name).join(','),
              name: value.item1.paidBy,
              time: DateTimeUtils.formatDateTimeString(value.item1.issuedAt),
              currency: value.item1.currencyCode,
              amount: value.item1.total.toDouble(),
              status: FormUtils.getStatus(
                  ReimburseModel.expense, value.item1.reimburseStatus, 0),
              isSelect: value.item2,
            ),
          ),
          if (lastItemInList == value.item1) AppSpaces.h85(context)
        ],
      ),
    );
  }

  Widget buildSliverHeader({String title, bool isFirst}) {
    final String _title = title.isEmpty ? "*" : title;
    return TransactionRecordTitleItem(
      title: _title,
      leftPadding: getDp(24),
      topPadding: getDp(20),
      hasBottomBorder: true,
      trailing: isFirst
          ? listBuilder<int>(
              selector: (_, __) => __.currentSelectList.length,
              builder: (BuildContext context, int value, Widget child) =>
                  PressedOpacityButton(
                onPressed:
                    value > 0 ? provider.onDeselectAll : provider.onSelectAll,
                padding: EdgeInsets.only(right: getDp(35), top: getDp(20)),
                child: Text(
                  value > 0 ? S.current.deselect_all : S.current.select_all,
                  style: TextStyle(
                    color: aceBlueColor,
                    fontSize: getSp(16),
                    fontWeight: FontWeight.w700,
                    height: 14 / 16,
                  ),
                ),
              ),
            )
          : null,
    );
  }

  String actionName(String operation) {
    switch (operation) {
      case "Reimburse Now":
        return S.current.continue_;
        break;
      case "Reimburse Later":
        return S.current.confirm;
        break;
      case "Reject":
        return S.current.reject;
        break;
      case "Delete":
        return S.current.delete;
        break;
      default:
        return operation;
    }
  }
}
